﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using CoreEx.Database.Linq.Translators;
using CoreEx.Database.Query.Expressions;
using LinFu.IoC.Configuration;

namespace CoreEx.Database.Linq.Implementation.Translators
{
    /// <summary>
    /// Translates a <see cref="Expression"/> into a <see cref="DbExpression"/> instance.
    /// </summary>
    [Implements(typeof(IExpressionTranslator_generic<Expression>))]
    public class ExpressionTranslatorGeneric : ExpressionTranslatorGenericBase<Expression>
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionTranslatorGeneric"/> class.
        /// </summary>
        /// <param name="translateResult">The <see cref="TranslateResult"/> that 
        /// provides aggregated information about the current query translation process.</param>
        public ExpressionTranslatorGeneric(TranslateResult translateResult)
            : base(translateResult)
        {
        }

        /// <summary>
        /// Translates a <see cref="Expression"/> into a <see cref="DbExpression"/> instance.
        /// </summary>
        /// <param name="expression">The <see cref="Expression"/> to translate.</param>
        /// <returns><see cref="DbExpression"/></returns>
        /// <seealso cref="ExpressionTranslatorGenericBase{TExpression}.Visit"/>
        public override DbExpression Translate(Expression expression)
        {            
            //Hand it off to the base class to figure out the actual 
            //expression translator to be used.
            var dbExpression = Visit(expression);
            return CreateFinalQuery();
        }
        

        private DbExpression CreateFinalQuery()
        {
            

            

            DbExpression fromClause = null;
            
            IList<DbExpression> projectionList = new List<DbExpression>();

            foreach (var tableSource in TranslateResult.TableSources.Values)
            {
                if (fromClause.IsNull())
                    fromClause = tableSource.TableExpression;
                else
                    fromClause = ExpressionFactory.Concat(fromClause, tableSource.TableExpression);

                if (tableSource.Projection != null)
                    projectionList.Add(tableSource.Projection.DbExpression);

            }
            var test = DbQueryFactory.Select(ExpressionFactory.List(projectionList)).From(fromClause);
            return test;
        }



    }
}
